package com.xiao.mall.message.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiao.mall.foundation.service.Criteria;
import com.xiao.mall.foundation.service.CurdService;
import com.xiao.mall.foundation.service.SpecificationBuilder;
import com.xiao.mall.foundation.service.SpecificationHelper;
import com.xiao.mall.message.rabbitmq.repository.NotificationRepository;
import com.xiao.mall.message.rabbitmq.repository.UserNotificationRepository;
import com.xiao.mall.message.service.dto.UserNotificationDto;
import com.xiao.mall.message.service.mapper.NotificationMapper;
import com.xiao.mall.message.service.mapper.UserNotificationMapper;
import com.xiao.mall.message.domain.Notification;
import com.xiao.mall.message.domain.UserNotification;
import com.xiao.mall.message.service.criteria.NotificationCriteria;
import com.xiao.mall.message.service.dto.NotificationDto;
import com.xiao.mall.message.service.dto.UserLoginDto;
import lombok.extern.slf4j.Slf4j;
//import org.springframework.amqp.rabbit.connection.CorrelationData;
//import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
public class NotificationService extends CurdService<Notification, NotificationDto, Long> {

    private final UserNotificationRepository userNotificationRepository;
    private final NotificationRepository notificationRepository;
    private final NotificationMapper notificationMapper;
    private final UserNotificationMapper userNotificationMapper;
   // private final RabbitTemplate rabbitTemplate;
    private final StringRedisTemplate stringRedisTemplate;
    private final SpecificationBuilder builder;


    protected NotificationService(NotificationRepository repository, NotificationMapper mapper,
                                  UserNotificationRepository userNotificationRepository, UserNotificationMapper userNotificationMapper,
//                                  RabbitTemplate rabbitTemplate,
                                  StringRedisTemplate stringRedisTemplate) {
        super(repository, mapper);
        this.notificationRepository = repository;
        this.notificationMapper = mapper;
        this.userNotificationRepository = userNotificationRepository;
        this.userNotificationMapper = userNotificationMapper;
       // this.rabbitTemplate = rabbitTemplate;
        this.stringRedisTemplate = stringRedisTemplate;
        builder = new SpecificationBuilder();
    }


    @Transactional(rollbackFor = Exception.class)
    public UserNotificationDto createChannelNotificationToUser(String userId, NotificationDto dto) {
        Notification notification = notificationMapper.toEntity(dto);
        notificationRepository.save(notification);

        //保存相应用户发送记录
        UserNotification userNotification = UserNotification.builder().userId(userId).mobile(dto.getMobile())
                .notification(notification).build();
        userNotificationRepository.save(userNotification);

        UserNotificationDto retDto = new UserNotificationDto();
        BeanUtils.copyProperties(dto,retDto);
        retDto.setUserId(userId);
      //  rabbitTemplate.convertSendAndReceive("exchange.fanout.message.notification", null, retDto, new CorrelationData(UUID.randomUUID().toString()));

        return retDto;
    }


    @Transactional(rollbackFor = Exception.class)
    public void userLoginBinding(UserLoginDto userLoginDto) throws JsonProcessingException {
        String userLoginInfoKey = String.format("user:last:login:hash");
        ObjectMapper objectMapper = new ObjectMapper();
        String userLoginDtoStr = objectMapper.writeValueAsString(userLoginDto);
        stringRedisTemplate.opsForHash().put(userLoginInfoKey, userLoginDto.getUserId(), userLoginDtoStr);
    }

    @Override
    protected Specification<Notification> createSpecification(Criteria criteria) {
        NotificationCriteria notificationCriteria = (NotificationCriteria) criteria;
        Specification<Notification> notificationSpecification = SpecificationHelper.create(Notification.class)
//                 .buildStringSpecification(notificationCriteria.getSender(), Notification_.sender)
                .build();
//        if (notificationCriteria.getNotificationType() != null &&
//                StringUtils.hasText(notificationCriteria.getNotificationType().getEquals())) {
////            notificationSpecification.and(builder.equalsSpecification(root -> root.get(Notification_.TYPE),
////                    NotificationType.valueOf(notificationCriteria.getNotificationType().getEquals())));
//        }
//
//        if (notificationCriteria.getNotificationTopic() != null
//                && StringUtils.hasText(notificationCriteria.getNotificationTopic().getEquals())) {
////            notificationSpecification.and(builder.equalsSpecification(root -> root.get(Notification_.TOPIC),
////                    NotificationTopic.valueOf(notificationCriteria.getNotificationType().getEquals())));
//        }
        return notificationSpecification;
    }


}
